//
//  StatisticManager.m
//  BaseProject
//
//  Created by KH_MoSi on 2020/11/5.
//  Copyright © 2020 王盼盼. All rights reserved.
//

#import "StatisticManager.h"
#import "TTUDIDManager.h"
#import "FMDBManager.h"
#import "StatisticBehaviorModel.h"
#import "ZXRequestBlock.h"
static StatisticManager *shareInstance = nil;
@interface StatisticManager ()
@property(nonatomic,strong)NSDate *startDate;//启动时刻
@property(nonatomic,strong)NSDate *aliveDate;//进入前台时刻
@property(nonatomic,strong)NSDate *backDate;//进入后台时刻
@property(nonatomic,assign)NSTimeInterval durationBack;//程序后台时长
@property(nonatomic,strong)NSDateFormatter *formatter;
@property(nonatomic,strong)NSMutableArray<NSNumber *> *durationArray;
@end

@implementation StatisticManager
+ (instancetype)shareManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareInstance = [[StatisticManager alloc]init];
        //NSLog(@"统计日活开始");
        [shareInstance initSetting];
    });
    return shareInstance;
}
- (void)initSetting {
    [self createProperty];
    [self addObserverAppStatusNoticefication];
    
    if (!kCloseProxy) {
        //网络防劫持 暂时写在这块
        [ZXRequestBlock handleRequest:^NSURLRequest *(NSURLRequest *request) {
            return request;
        }];
        [ZXRequestBlock disableHttpProxy];
        [ZXRequestBlock disableHttpDns];
    }
}
- (void)createProperty
{
    self.enableExceptionLog = YES;
    self.logStrategy = LogSendStrategyDay;
}
#pragma mark - setter方法
- (void)setEnableExceptionLog:(BOOL)enableExceptionLog
{
    _enableExceptionLog = enableExceptionLog;
    if (enableExceptionLog) {
        NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);
    }
}
#pragma mark - crash回调
void UncaughtExceptionHandler(NSException * exception)
{
    //NSArray *arr = [exception callStackSymbols];
    //崩溃的原因
    NSString *reason = [exception reason];
    //可以有崩溃的原因(数组越界,字典nil,调用未知方法...) 崩溃的控制器以及方法
    NSString *name = [exception name];
    NSString *crashLogInfo = [NSString stringWithFormat:@"exception type : %@ \n crash reason : %@ \n call stack", name, reason];
    NSLog(@"异常错误报告：%@",crashLogInfo);
    //[selfClass markStatisticLogWithLogName:crashLogInfo Duration:0.0];
    //[[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"https://www.baidu.com"]];
    
    //NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    //[formatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
    //[FMDBManager addDataWithName:@"程序闪退" withDate:[formatter stringFromDate:[NSDate date]] withDuration:0 withFlag:100];
}
#pragma mark - 系统通知
- (void)addObserverAppStatusNoticefication
{
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onAppUIApplicationDidFinishLaunchingNotification:) name:UIApplicationDidFinishLaunchingNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onAppWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onAppDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onAppDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onLoginSuccess:) name:@"BA_LoginSuccess" object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onLogOutSuccess:) name:@"BA_LogOutSuccess" object:nil];
}
//程序开启
- (void)onAppUIApplicationDidFinishLaunchingNotification:(NSNotification *)noti
{
    //NSLog(@"系统通知-onAppUIApplicationDidFinishLaunchingNotification");
    UIDevice *device = [[UIDevice alloc]init];
//    NSString *name = device.name;
//    NSString *type = device.localizedModel;
//    NSString *systemName = device.systemName;
//    NSString *systemVersion = device.systemVersion;
//    NSLog(@"%@ %@ %@ %@",name,type,systemName,systemVersion);
    self.startDate = [NSDate date];
    //NSLog(@"startDate:%@",self.startDate);
    if (self.logStrategy == LogSendStrategyDay) {
        [self sendLogsToServer];
    }
    //[FMDBManager addDataWithName:@"程序启动" withDate:[self.formatter stringFromDate:[NSDate date]] withDuration:0 withFlag:100];
}
//程序进程结束即退出程序
- (void)onAppWillTerminate:(NSNotification *)noti
{
    [self updateOnlineTimeWith:[Utilities getCurrentTimestamp] Type:BA_UpdateTimeType_terminate];

    //NSLog(@"系统通知-onAppWillTerminate");
    //双击home 结束程序 会先走程序进入后台（onAppDidEnterBackground） 然后走程序结束（onAppWillTerminate）
    NSString *isLogin;
    if ([TTUserModel sharedObject].token.length > 0) {
        isLogin = @"1";
    } else {
        isLogin = @"0";
    }
    [self insertDataWithIsLogin:isLogin withName:@"程序退出"];
}

//程序进入前台
- (void)onAppDidBecomeActive:(NSNotification *)noti
{
    [self updateOnlineTimeWith:[Utilities getCurrentServerTimestamp] Type:BA_UpdateTimeType_openApp];

    //NSLog(@"系统通知-onAppDidBecomeActive");
    self.aliveDate = [NSDate date];
    if (self.backDate) {
        NSTimeInterval timeGap = [[NSDate date]timeIntervalSinceDate:self.backDate];
        //NSLog(@"timeGap:%f",timeGap);
    }
    //[FMDBManager addDataWithName:@"进入前台" withDate:[self.formatter stringFromDate:[NSDate date]] withDuration:0 withFlag:100];
    if (self.backDate && ([[NSDate date] timeIntervalSinceDate:self.backDate] > 1)) {
        [self.durationArray addObject:[NSNumber numberWithFloat:[[NSDate date] timeIntervalSinceDate:self.backDate]]];
        //NSLog(@"%@",self.durationArray);
    }
}
//程序进入后台
- (void)onAppDidEnterBackground:(NSNotification *)noti
{
    [self updateOnlineTimeWith:[Utilities getCurrentServerTimestamp] Type:BA_UpdateTimeType_terminate];
    self.backDate = [NSDate date];
    //[FMDBManager addDataWithName:@"进入后台" withDate:[self.formatter stringFromDate:[NSDate date]] withDuration:0 withFlag:100];
}
- (void)onLoginSuccess:(NSNotification *)noti
{
    [self insertDataWithIsLogin:@"0" withName:@"登出时间"];
    self.startDate = [NSDate date];
}

- (void)onLogOutSuccess:(NSNotification *)noti
{
    [self insertDataWithIsLogin:@"1" withName:@"登录时间"];
    self.startDate = [NSDate date];
    
}
#pragma mark - 插入数据
- (void)insertDataWithIsLogin:(NSString *)isLogin withName:(NSString *)name
{
    NSTimeInterval total = [[NSDate date]timeIntervalSinceDate:self.startDate];
    //NSLog(@"总时间：%f",total);
    for (NSInteger index = 0; index < self.durationArray.count; index ++) {
        NSNumber *number = self.durationArray[index];
        total = total - number.floatValue;
    }
    //NSLog(@"总时间：%f",total);
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    [FMDBManager addDataWithName:name withDate:[self.formatter stringFromDate:[NSDate date]] withDuration:total withFlag:[formatter stringFromDate:[NSDate date]] withIsLogin:isLogin];
}
#pragma mark - 发送策略
- (void)sendLogsToServer
{
    NSArray<NSDictionary *> *array = [FMDBManager queryData];
    if (array.count == 0) {
        return;
    }
    //model化
    NSMutableArray<StatisticBehaviorModel *> *mutableArray = [NSMutableArray array];
    for (NSInteger index = 0; index < array.count; index ++) {
        NSDictionary *itemDic = array[index];
        [mutableArray addObject:[StatisticBehaviorModel modelWithJSON:itemDic]];
    }
    //获取某一个分类的内容
    NSString *flag = mutableArray.firstObject.flag;
    NSTimeInterval totalDuration = 0;
    NSTimeInterval totalDuration1 = 0;
    for (NSInteger index = 0; index < mutableArray.count; index ++) {
        StatisticBehaviorModel *itemModel = mutableArray[index];
        if ([itemModel.flag isEqualToString:flag]) {
            totalDuration = totalDuration + itemModel.duration;
        }
        if ([itemModel.isLogin isEqualToString:@"1"]) {
            totalDuration1 = totalDuration1 + itemModel.duration;
        }
        //NSLog(@"日活记录：%@",[itemModel modelToJSONObject]);
    }
    //时间和现在不一样即可
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *nowDate = [formatter stringFromDate:[NSDate date]];
    if (![nowDate isEqualToString:flag]) {
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        [parameters setValue:flag forKey:@"dateTime"];
        [parameters setValue:[[TTUserModel sharedObject].userModelDefault valueForKey:@"BA_registrationID"] forKey:@"registrationID"];
        [parameters setValue:[NSString stringWithFormat:@"%0.2f",totalDuration] forKey:@"onlineDuration"];
        if ([TTUserModel sharedObject].token.length > 0) {
            [parameters setValue:@"1" forKey:@"isLogin"];
            [parameters setValue:[TTUserModel sharedObject].username forKey:@"userName"];
            [parameters setValue:[NSString stringWithFormat:@"%0.2f",totalDuration1] forKey:@"loginOnlineDuration"];
        } else {
            [parameters setValue:@"2" forKey:@"isLogin"];
        }
        NSLog(@"日活参数：parameters:%@",parameters);
        NSString *url = [NSString stringWithFormat:@"%@%@",TT_Global_Api_Domain,@"/userActiveQuantity/insert"];
        [TTHttpManager postRequestWithUrl:url TimeOut:10 PostData:parameters FinishBlock:^(id  _Nonnull data) {
            [FMDBManager removeData];
        } FailedBlock:^(NSError * _Nonnull error) {
            
        }];
    }
}
#pragma mark - lazy懒加载
- (NSDateFormatter *)formatter
{
    if (!_formatter) {
        NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
        [formatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
        _formatter = formatter;
    }
    return _formatter;
}
- (NSMutableArray<NSNumber *> *)durationArray
{
    if (!_durationArray) {
        _durationArray = [NSMutableArray array];
    }
    return _durationArray;
}
#pragma mark - 新增商品浏览请求
- (void)insertBrowseUserActiveQuantityWithToolType:(NSString *)toolType WithInTime:(NSString *)inTime
{
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    [parameters setValue:@"8" forKey:@"type"];
    [parameters setValue:toolType forKey:@"toolType"];
    [parameters setValue:inTime forKey:@"inTime"];
    [parameters setValue:[TTUserModel sharedObject].userId forKey:@"userId"];
    NSLog(@"parameters:%@",parameters);
    [TTHttpManager postRequestWithUrl:[NSString stringWithFormat:@"%@%@",TT_Global_Api_Domain,@"/userActiveQuantity/insertBrowse"] TimeOut:10 PostData:parameters FinishBlock:^(id  _Nonnull responseObject) {
        NSLog(@"%@",responseObject);
    } FailedBlock:^(NSError * _Nonnull error) {
        
    }];
}
- (void)insertBrowseUserActiveQuantityWithType:(NSString *)type
{
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    [parameters setValue:type forKey:@"type"];
    [parameters setValue:[TTUserModel sharedObject].userId forKey:@"userId"];
    [TTHttpManager postRequestWithUrl:[NSString stringWithFormat:@"%@%@",TT_Global_Api_Domain,@"/userActiveQuantity/insertBrowse"] TimeOut:10 PostData:parameters FinishBlock:^(id  _Nonnull responseObject) {
        NSLog(@"%@",responseObject);
    } FailedBlock:^(NSError * _Nonnull error) {
        
    }];
}

- (void)updateOnlineTimeWith:(NSTimeInterval)time Type:(BA_UpdateTimeType)type {
    switch (type) {
        case BA_UpdateTimeType_openApp:{//记录启动时间
            [[TTUserModel sharedObject].userModelDefault setDouble:time forKey:@"TT_openAppTime"];
            [[TTUserModel sharedObject].userModelDefault synchronize];
        } break;
        case BA_UpdateTimeType_loginAccount:{//记录登录时间
            [[TTUserModel sharedObject].userModelDefault setDouble:time forKey:@"TT_loginTime"];
            [[TTUserModel sharedObject].userModelDefault synchronize];
        } break;
        case BA_UpdateTimeType_logoutAccount:{//退出登录提交
            [[TTUserModel sharedObject].userModelDefault setDouble:time forKey:@"TT_logOutTime"];
            [[TTUserModel sharedObject].userModelDefault synchronize];
            [self request_uploadTimeWithType:BA_UpdateTimeType_logoutAccount];
        } break;
        case BA_UpdateTimeType_terminate:{//杀死app提交
            [self request_uploadTimeWithType:BA_UpdateTimeType_terminate];
        } break;
        default:
            break;
    }
}

- (void)request_uploadTimeWithType:(BA_UpdateTimeType)type {
    
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    [parameters setValue:[Utilities getFromNSUserDefaults:@"BA_registrationID"] forKey:@"registrationID"];
    [parameters setValue:@([TTUserModel sharedObject].openAppTime) forKey:@"onlineDuration"];
    [parameters setValue:@([Utilities getCurrentServerTimestamp]) forKey:@"endDuration"];
    [parameters setValue:[TTUserModel sharedObject].username forKey:@"userName"];
    [parameters setValue:[TTUserModel sharedObject].userId forKey:@"userId"];

    if ([TTUserModel sharedObject].token.length > 0) {
        [parameters setValue:@(1) forKey:@"isLogin"];
    } else {
        [parameters setValue:@(0) forKey:@"isLogin"];
    }
    
    switch (type) {
        case BA_UpdateTimeType_logoutAccount:{
            [parameters setValue:@(1) forKey:@"type"];
            
        } break;
        case BA_UpdateTimeType_terminate:{
            [parameters setValue:@(2) forKey:@"type"];
            
        } break;
        default:
            break;
    }
    
    NSLog(@"insertNew param = %@",parameters);
    NSString *url = [NSString stringWithFormat:@"%@%@",TT_Global_Api_Domain,@"/userActiveQuantity/insertNew"];
    [TTHttpManager postRequestWithUrl:url TimeOut:10 PostData:parameters FinishBlock:^(id  _Nonnull responseObject) {
    } FailedBlock:^(NSError * _Nonnull error) {

    }];
}

- (void)uploadClassCategory:(NSString *)classId {
    [self request_uploadWithClass:classId];
}

- (void)request_uploadWithClass:(NSString *)classId {
    
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    [parameters setValue:[TTUserModel sharedObject].token.length>0?@"1":@"2" forKey:@"equipType"];
    [parameters setValue:@"3" forKey:@"type"];
    [parameters setValue:classId forKey:@"classId"];
    [parameters setValue:[TTUserModel sharedObject].userId forKey:@"userId"];
    [parameters setValue:[TTUDIDManager getUniqueDeviceID] forKey:@"deviceUniqueNo"];
    
    //NSLog(@"insertStatistics param = %@",parameters);
    NSString *url = [NSString stringWithFormat:@"%@%@",TT_Global_Api_Domain,@"/userActiveQuantity/insertStatistics"];
    [TTHttpManager postRequestWithUrl:url TimeOut:10 PostData:parameters FinishBlock:^(id  _Nonnull responseObject) {
    } FailedBlock:^(NSError * _Nonnull error) {

    }];
}



@end
